using System;

using NUnit.Framework;

using StructureMap.AutoMocking;
using StructureMap.TypeMockAutoMocker;

using TypeMock.ArrangeActAssert;

namespace StructureMap.TypeMockAutoMocker
{
	public abstract class AaaAutoMockerTesterBase<TCutWithAbstractMock, TCutWithConcreteMock>: AutoMockerTesterBase<TCutWithAbstractMock, TCutWithConcreteMock> where TCutWithAbstractMock: class, IConsumer where TCutWithConcreteMock: class, IConsumer
	{
		protected override MockMode MockMode
		{
			get { return MockMode.AAA; }
		}

		[Test]
		public void CanUseAAASemanticsOnAbstractProviderForMocking()
		{
			var consumerAutoMocker = createAutoMockerWithAbstractMock();
			var provider = consumerAutoMocker.Get<IMock>();
			// Act
			consumerAutoMocker.PartialMockTheClassUnderTest();
			consumerAutoMocker.ClassUnderTest.CallMock(7);
			// Assert
			Isolate.Verify.WasCalledWithExactArguments(() => provider.Call(7));
		}

		[Test]
		public void CanUseAAASemanticsWithAbstractProviderForStubbing()
		{
			var consumerAutoMocker = createAutoMockerWithAbstractMock();
			var provider = consumerAutoMocker.Get<IMock>();
			// Arrange
			Isolate.WhenCalled(() => provider.Call(7)).WillReturn(8);
			// Act
			consumerAutoMocker.PartialMockTheClassUnderTest();
			Assert.AreEqual(8, consumerAutoMocker.ClassUnderTest.CallMock(7), "the stub didn't return the expected value for a stub. Somehow the AutoMocker hasn't setup it correctly");
		}

		[Test]
		public void CanUseAAASemanticsWithConcreteProviderForMocking()
		{
			var consumerAutoMocker = createAutoMockerWithConcreteMock();
			var provider = consumerAutoMocker.Get<ConcreteProvider>();
			// Act
			consumerAutoMocker.PartialMockTheClassUnderTest();
			consumerAutoMocker.ClassUnderTest.CallMock(7);
			// Assert
			Isolate.Verify.WasCalledWithExactArguments(() => provider.Call(7));
		}

		[Test]
		public void CanUseAAASemanticsWithConcreteProviderForStubbing()
		{
			var consumerAutoMocker = createAutoMockerWithConcreteMock();
			var provider = consumerAutoMocker.Get<ConcreteProvider>();
			// Arrange
			Isolate.WhenCalled(() => provider.Call(7)).WillReturn(8);
			// Act
			consumerAutoMocker.PartialMockTheClassUnderTest();
			Assert.AreEqual(8, consumerAutoMocker.ClassUnderTest.CallMock(7), "the stub didn't return the expected value for a stub. Somehow the AutoMocker hasn't setup it correctly");
		}
	}
}